import 'package:flutter/material.dart';
import 'package:htxd_flutter_mapbox_sdk/mapbox/util/DrawLandWebSocketListener.dart';
import 'package:mapbox_maps_flutter/mapbox_maps_flutter.dart';

import '../../mapview/base_map_control.dart';
import '../../util/screen_util.dart';
import '../../util/toast_util.dart';
import '../../util/uuid_util.dart';
import '../base_draw_map_view.dart';
import '../land/draw_land.dart';
import '../measure/measure_area.dart';
import '../measure/measure_length.dart';
import 'draw_type.dart';

/// 开始移动
/// drawType 绘制类型
/// selectPosition 选择的是哪个点
/// 点的坐标集合
typedef LandStartMove = Function(
    DrawType drawType, int selectPosition, List<Position> positions);

/// 移动过程中
typedef LandMoving = Function(Offset offset);

/// 移动结束
typedef LandMoveEnd = Function();

/// 地块操作管理类
class DrawLandManager {
  LandStartMove? landStartMove;
  LandMoving? landMoving;
  LandMoveEnd? landMoveEnd;
  late final MapBoxControl _control;
  late List<DrawLand> _drawLandList;
  late List<MeasureArea> _measureAreaList;
  late List<MeasureLength> _measureLengthList;
  DrawLand? _drawLand;
  MeasureArea? _measureArea;
  MeasureLength? _measureLength;
  DrawType? _drawType;
  MapBoxControl? _mirrorControl;

  /// 开始勾画
  final OnLandStartDraw? onLandStartDraw;

  /// 添加点
  final OnLandAddPoint? onLandAddPoint;

  /// 撤销
  final OnLandUndo? onLandUndo;

  /// 删除
  final OnLandDelete? onLandDelete;

  /// 完成
  final OnLandComplete? onLandComplete;

  /// 地图点击操作
  final OnMapTapListener? onMapTapListener;

  /// 是否是触摸
  bool _isTouch = false;

  DrawLandManager(this._control,
      {this.landStartMove,
      this.landMoving,
      this.landMoveEnd,
      this.onLandStartDraw,
      this.onLandAddPoint,
      this.onLandUndo,
      this.onLandDelete,
      this.onLandComplete,
      this.onMapTapListener}) {
    _drawLandList = [];
    _measureAreaList = [];
    _measureLengthList = [];
  }

  /// 手指按下事件
  void downEvent(PointerDownEvent event) async {
    if (_drawType == null) {
      _isTouch = false;
      return;
    }

    var localPosition = event.localPosition;
    switch (_drawType!) {
      case DrawType.DRAW_LAND:
        if (_drawLand != null) {
          _isTouch = await _drawLand!.touchPoint(
              ScreenCoordinate(x: localPosition.dx, y: localPosition.dy));
        }
        break;
      case DrawType.MEASURE_AREA:
        if (_measureArea != null) {
          _isTouch = await _measureArea!.touchPoint(
              ScreenCoordinate(x: localPosition.dx, y: localPosition.dy));
        }
        break;
      case DrawType.MEASURE_LENGTH:
        if (_measureLength != null) {
          _isTouch = await _measureLength!.touchPoint(
              ScreenCoordinate(x: localPosition.dx, y: localPosition.dy));
        }
        break;
    }
    if (_isTouch) {
      GesturesSettings gesturesSettings =
          await _control.mapboxMap.gestures.getSettings();
      gesturesSettings.scrollEnabled = false;
      await _control.mapboxMap.gestures.updateSettings(gesturesSettings);

      if (landStartMove != null) {
        switch (_drawType!) {
          case DrawType.DRAW_LAND:
            if (_drawLand != null) {
              _drawLand!.startMove();
              landStartMove!(
                  _drawType!, _drawLand!.selectIndex, _drawLand!.positions);
            }
            break;
          case DrawType.MEASURE_AREA:
            if (_measureArea != null) {
              _measureArea!.startMove();
              landStartMove!(_drawType!, _measureArea!.selectIndex,
                  _measureArea!.positions);
            }
            break;
          case DrawType.MEASURE_LENGTH:
            if (_measureLength != null) {
              _measureLength!.startMove();
              landStartMove!(_drawType!, _measureLength!.selectIndex,
                  _measureLength!.positions);
            }
            break;
        }
      }
    }
  }

  /// 手指移动事件
  void moveEvent(PointerMoveEvent event) {
    if (_drawType == null || _isTouch == false) {
      return;
    }
    if (landMoving != null) {
      landMoving!(event.localPosition);
    }
  }

  /// 手指抬起事件
  void upEvent(PointerUpEvent event) async {
    if (_drawType == null || _isTouch == false) {
      _isTouch = false;
      return;
    }
    if (landMoveEnd != null) {
      landMoveEnd!();
    }

    var localPosition = event.localPosition;
    ScreenCoordinate coordinate = ScreenCoordinate(
        x: localPosition.dx * MyScreenUtil.pixelRatio,
        y: localPosition.dy * MyScreenUtil.pixelRatio);

    switch (_drawType!) {
      case DrawType.DRAW_LAND:
        if (_drawLand != null) {
          _drawLand!.endMove(coordinate);
          print("移动一个点");
          DrawLandWebSocketListener.addPoint(_drawLand?.posi ?? []);
        }
        break;
      case DrawType.MEASURE_AREA:
        if (_measureArea != null) {
          _measureArea!.endMove(coordinate);
        }
        break;
      case DrawType.MEASURE_LENGTH:
        if (_measureLength != null) {
          _measureLength!.endMove(coordinate);
        }
        break;
    }
    _isTouch = false;
    GesturesSettings gesturesSettings =
        await _control.mapboxMap.gestures.getSettings();
    gesturesSettings.scrollEnabled = true;
    _control.mapboxMap.gestures.updateSettings(gesturesSettings);
  }

  /// 手指点击地图事件
  void mapClickEvent(Position position) {
    // 如果正在滑动，其实这种情况是不可能发生的
    if (_isTouch) {
      return;
    }
    if (_drawType == null) {
      for (var drawLand in _drawLandList) {
        if (drawLand.isSelectLand(position)) {
          _drawType = DrawType.DRAW_LAND;
          _drawLand = drawLand;
          return;
        }
      }
      if (onMapTapListener != null) {
        ScreenCoordinate coordinate = ScreenCoordinate(
            x: position.lat.toDouble(), y: position.lng.toDouble());
        onMapTapListener!(coordinate);
      }
      return;
    }
    switch (_drawType!) {
      case DrawType.DRAW_LAND:
        if (_drawLand != null) {
          _drawLand?.add(position);
          DrawLandWebSocketListener.addPoint(_drawLand?.posi ?? []);
        }
        break;
      case DrawType.MEASURE_AREA:
        if (_measureArea != null) {
          _measureArea?.add(position);
        }
        break;
      case DrawType.MEASURE_LENGTH:
        if (_measureLength != null) {
          _measureLength?.add(position);
        }
        break;
    }
    if (onLandAddPoint != null) {
      onLandAddPoint!();
    }
  }

  /// 添加点
  void addPoint(Position position) {
    if (_drawType == null) {
      return;
    }
    switch (_drawType!) {
      case DrawType.DRAW_LAND:
        if (_drawLand != null) {
          _drawLand?.add(position);
          DrawLandWebSocketListener.addPoint(_drawLand?.posi ?? []);
        }
        break;
      case DrawType.MEASURE_AREA:
        if (_measureArea != null) {
          _measureArea?.add(position);
        }
        break;
      case DrawType.MEASURE_LENGTH:
        if (_measureLength != null) {
          _measureLength?.add(position);
        }
        break;
    }
    if (onLandAddPoint != null) {
      onLandAddPoint!();
    }
  }

  /// 开始勾画
  void startDraw(DrawType drawType) {
    _drawType = drawType;
    switch (_drawType!) {
      case DrawType.DRAW_LAND:
        _drawLand = DrawLand(_control, UuidUtil.instance.getUuid());
        _drawLandList.add(_drawLand!);
        break;
      case DrawType.MEASURE_AREA:
        _measureArea = MeasureArea(_control, UuidUtil.instance.getUuid());
        _measureAreaList.add(_measureArea!);
        break;
      case DrawType.MEASURE_LENGTH:
        _measureLength = MeasureLength(_control, UuidUtil.instance.getUuid());
        _measureLengthList.add(_measureLength!);
        break;
    }
    if (onLandStartDraw != null) {
      onLandStartDraw!();
    }
  }

  /// 删除操作
  Future<void> delete() async {
    if (_drawLand != null) {
      _drawLandList.remove(_drawLand!);
      await _drawLand?.delete();
      _drawLand = null;
    }
    for (var value in _measureAreaList) {
      await value.delete();
    }
    if (_measureArea != null) {
      await _measureArea?.delete();
      _measureArea = null;
    }
    _measureAreaList.clear();

    for (var value in _measureLengthList) {
      await value.delete();
    }
    if (_measureLength != null) {
      await _measureLength?.delete();
      _measureLength = null;
    }
    _measureLengthList.clear();
    _drawType = null;

    if (onLandDelete != null) {
      onLandDelete!();
    }
  }

  /// 撤销操作
  void undo() {
    if (_drawType == null) {
      return;
    }
    switch (_drawType!) {
      case DrawType.DRAW_LAND:
        if (_drawLand != null) {
          _drawLand?.undo();
          //撤销
          DrawLandWebSocketListener.addPoint(_drawLand?.posi ?? []);
        }
        break;
      case DrawType.MEASURE_AREA:
        if (_measureArea != null) {
          _measureArea?.undo();
        }
        break;
      case DrawType.MEASURE_LENGTH:
        if (_measureLength != null) {
          _measureLength?.undo();
        }
        break;
    }
    if (onLandUndo != null) {
      onLandUndo!();
    }
  }

  /// 完成操作
  void complete() {
    if (_drawType == null) {
      return;
    }
    switch (_drawType!) {
      case DrawType.DRAW_LAND:
        if (_drawLand != null) {
          if (_drawLand!.positions.length < 3) {
            ToastUtil.showToast('画地块最少需要三个点');
            return;
          }
          _drawLand!.complete();
        }
        _drawLand = null;
        break;
      case DrawType.MEASURE_AREA:
        if (_measureArea != null) {
          if (_measureArea!.positions.length < 3) {
            ToastUtil.showToast('测面积最少需要三个点');
            return;
          }
          _measureArea!.complete();
        }
        _measureArea = null;
        break;
      case DrawType.MEASURE_LENGTH:
        if (_measureLength != null) {
          if (_measureLength!.positions.length < 2) {
            ToastUtil.showToast('测距离最少需要两个点');
            return;
          }
          _measureLength!.complete();
        }
        _measureLength = null;
        break;
    }
    _drawType = null;
    if (onLandComplete != null) {
      onLandComplete!();
    }
  }

  Future<void> dispose() async {
    _control.dispose();
    _mirrorControl?.dispose();
  }

  List<DrawLand> get drawLandList => _drawLandList;

  MapBoxControl get control => _control;

  DrawLand? get drawLand => _drawLand;

  /// 切换底图
  void switchLayer(ShowType showType) {
    _control.showTypeLayer(showType);
    _mirrorControl?.showTypeLayer(showType);
  }

  set mirrorControl(MapBoxControl value) {
    _mirrorControl = value;
  }
}
